package com.example.interesting.distributed.lock.realize.config;

import com.example.interesting.distributed.lock.realize.DistributedLockTemplate;
import com.example.interesting.distributed.lock.realize.aop.LockAop;
import com.example.interesting.distributed.lock.realize.aop.LockMethodInterceptor;
import com.example.interesting.distributed.lock.realize.properties.DistributedLockProperties;
import com.example.interesting.distributed.lock.realize.strategy.*;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.util.List;

/**
 * @author fyw
 * @version 1.0
 * @description: 分布式锁配置类
 * @date 2024/3/16 14:34
 */
@Configuration
public class DistributedLockConfig {


    @Bean
    public DistributedLockProperties distributedLockProperties() {
        return new DistributedLockProperties();
    }

    @Bean
    public DistributedLockTemplate distributedLockTemplate(List<DistributedLockExecutorStrategy> executorStrategies,
                                                           DistributedLockProperties distributedLockProperties) {
        return new DistributedLockTemplate(distributedLockProperties, executorStrategies);
    }

    @Bean
    @Order(Integer.MIN_VALUE)
    public DistributedLockExecutorStrategy distributedLockExecutorStrategy(RedissonClient redissonClient) {
        return new DefaultDistributedLockExecutorStrategy(redissonClient);
    }
    @Bean
    @ConditionalOnMissingBean
    public DistributedLockKeyBuilder distributedLockKeyBuilder(BeanFactory beanFactory) {
        return new DefaultDistributedLockKeyBuilder(beanFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    public DistributedLockFailureStrategy distributedLockFailureStrategy() {
        return new DefaultDistributedLockFailureStrategy();
    }
    @Bean
    public LockMethodInterceptor lockMethodInterceptor(DistributedLockProperties distributedLockProperties,
                                                       DistributedLockTemplate distributedLockTemplate,
                                                       List<DistributedLockKeyBuilder> primaryKeyBuilders,
                                                       List<DistributedLockFailureStrategy> primaryFailures) {
        return new LockMethodInterceptor(distributedLockProperties, distributedLockTemplate,
                primaryKeyBuilders, primaryFailures);
    }




    @Bean
    public LockAop lockAop(LockMethodInterceptor lockMethodInterceptor) {
        return new LockAop(lockMethodInterceptor, Ordered.HIGHEST_PRECEDENCE);
    }
}
